Skip to content

Use both sides of type context for generic type inference (part 1) - #22286

Open
ilevkivskyi wants to merge 14 commits into
python:masterfrom
ilevkivskyi:new-inference
Open

ilevkivskyi wants to merge 14 commits into
python:masterfrom
ilevkivskyi:new-inference

Conversation

@ilevkivskyi

@ilevkivskyi ilevkivskyi commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Ref #22063

I think this is the right thing to do, even though this unfortunately (but unsurprisingly) causes some visible slow-down (because we infer 2-3x more constraints):

master                    4.013s (0.0%)  | stdev 0.011s 
new-inference             4.081s (+1.7%) | stdev 0.005s

I add couple micro-optimizations in relevant code paths to minimize the impact.

The implementation is generally straightforward: use both sides buy default, and only fall back to outer context if there are problems (to give consistent type errors). My plan is to split the change into few smaller things:

  1. Basic implementation of the idea (this PR).
  2. Targeted improvements of meet/join (as needed).
  3. Targeted improvements to the solver such us meet sorting and/or priming.
  4. Update the second pass of argument inference in the same manner.
  5. Remove (most of) existing special-casing (depends on step 4).
    5a. Fix false-negative bug due to Any leaking from partial context. This is present on master and quite benign, but may happen more often with the new logic.

For now I added just a few test to illustrate the core idea (plus one test case that I find amusing). I will investigate the mypy_primer and mypy-issues, and probably will add some more tests.

cc @JukkaL @hauntsaninja

@ilevkivskyi

Copy link
Copy Markdown
Member Author

I will also run the primer with performance impact reported, I skimmed through logs and found that optuna got ~6x slower. I will investigate that first.

@ilevkivskyi

Copy link
Copy Markdown
Member Author

After quick look at mypy-issues this fixes ~25 bugs. I will take a more detailed look on the weekend. Btw to clarify, this PR should handle ~90% of all potential fixes (as well as ~90% of all performance impact).

@github-actions

This comment has been minimized.

@ilevkivskyi

Copy link
Copy Markdown
Member Author

Oh, it looks like I forgot to refresh formal_to_actual somewhere, likely an easy fix. Otherwise the primer looks good, there are a handful of new errors, I will take a look at those as well.

@ilevkivskyi

Copy link
Copy Markdown
Member Author

Btw, it looks like django-stubs is crashing on master.

django-stubs (https://github.com/typeddjango/django-stubs)
  error: INTERNAL ERROR -- Please try using mypy master on GitHub:
- version: 2.5.0+dev.8fdf43736393353c6c7291d1cd33c7d9dc112acc
+ version: 2.5.0+dev.831e3d19a4e84cd8dee8b4456534a995f6ca4227

@ilevkivskyi

Copy link
Copy Markdown
Member Author

The error is ModuleNotFoundError: No module named 'psycopg2' so likely a problem with dependencies config in mypy_primer.

ilevkivskyi added a commit to ilevkivskyi/mypy_primer that referenced this pull request Oct 24, 2026
@github-actions

This comment has been minimized.

@ilevkivskyi

Copy link
Copy Markdown
Member Author

OK, some updates:

  • Performance issue in optuna I mentioned before was caused by a crash, all looks OK now. There are some real regressions, but they are few percent.
  • Looks like majority of fixes in the primer are from list[OneType] + list[OtherType], which was previously rejected.
  • Couple new Returning "Any" errors may be caused by items 5a I mentioned in PR description (pre-existing bug exposed by this PR)
  • There are half a dozen new errors where a join of type objects and/or complex callables is wrong (i.e. not actually a join). They all come from pytest.mark.parametrize(), where type context is Iterable[object] so it used to work before, i.e. this is item 2 from PR description. I will try to fix.
  • There are half a dozen errors in homeassistant related to recursive types. I think I know what is going on there, likely caused by one of my micro-optimizations.

JelleZijlstra pushed a commit to hauntsaninja/mypy_primer that referenced this pull request Oct 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

kornia (https://github.com/kornia/kornia)
- kornia/models/efficient_vit/nn/act.py:36: error: Dict entry 4 has incompatible type "str": "partial[Any]"; expected "str": "type[Any]"  [dict-item]

optuna (https://github.com/optuna/optuna): 1.08x slower (74.2s -> 79.9s in single noisy sample)

spark (https://github.com/apache/spark)
- python/pyspark/pandas/groupby.py:3530: error: Argument 2 to "zip" has incompatible type "list[Any | tuple[Any, ...]] | Hashable"; expected "Iterable[Any | tuple[Any, ...]]"  [arg-type]
+ python/pyspark/pandas/groupby.py:3530: error: Argument 2 to "zip" has incompatible type "list[Hashable | Any] | Hashable | list[Any | tuple[Any, ...]]"; expected "Iterable[Hashable | Any]"  [arg-type]
+ python/pyspark/ml/util.py:1169: error: Unused "type: ignore" comment  [unused-ignore]
+ python/pyspark/ml/classification.py:3990: error: Unused "type: ignore" comment  [unused-ignore]

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/utilities/callables/__init__.py:768: error: Incompatible types in assignment (expression has type "list[None]", variable has type "list[expr | None]")  [assignment]
- src/prefect/utilities/callables/__init__.py:768: note: "list" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
- src/prefect/utilities/callables/__init__.py:768: note: Consider using "Sequence" instead, which is covariant
- src/prefect/utilities/callables/__init__.py:770: error: Unsupported operand types for + ("list[None]" and "list[expr | None]")  [operator]
+ src/prefect/client/orchestration/__init__.py:1186: error: Function does not return a value (it only ever returns None)  [func-returns-value]
+ src/prefect/server/events/jinja_filters.py:86: error: Unused "type: ignore" comment  [unused-ignore]
- src/prefect/flow_engine.py:2402: error: Unsupported operand types for | ("dict[str, str]" and "dict[str, str | None]")  [operator]
- src/prefect/cli/deploy/_core.py:402: error: Incompatible types in assignment (expression has type "Any | None", variable has type "bool")  [assignment]

operator (https://github.com/canonical/operator)
- ops/model.py:2985: error: Argument 2 to "_list_recursive" of "Container" has incompatible type "str | Path"; expected "Path"  [arg-type]
- ops/model.py:3068: error: Argument 2 to "_list_recursive" of "Container" has incompatible type "str | Path"; expected "Path"  [arg-type]
- ops/_private/harness.py:4051: error: Argument 3 to "_notice_matches" of "_TestingPebbleClient" has incompatible type "set[NoticeType | str] | None"; expected "set[str] | None"  [arg-type]

altair (https://github.com/vega/altair): 1.13x slower (249.7s -> 281.3s in single noisy sample)

zulip (https://github.com/zulip/zulip): 1.09x slower (190.9s -> 208.2s in single noisy sample)
- zerver/lib/display_recipient.py:84: error: Argument 1 to "list" has incompatible type "QuerySet[Any, dict[str, Any]]"; expected "Iterable[UserDisplayRecipient]"  [arg-type]
+ zerver/lib/display_recipient.py:84: error: Argument 1 to "list" has incompatible type "QuerySet[Any, dict[str, Any]]"; expected "Iterable[TypedDict({'email': str, 'full_name': str, 'id': int, 'is_mirror_dummy': bool})]"  [arg-type]

scrapy (https://github.com/scrapy/scrapy)
+ tests/test_pipeline_files.py:1033: error: Unused "type: ignore" comment  [unused-ignore]
+ scrapy/commands/parse.py:159: error: Returning Any from function declared to return "Iterable[Any] | Deferred[Any]"  [no-any-return]
+ scrapy/commands/parse.py:160: error: Returning Any from function declared to return "Iterable[Any] | Deferred[Any]"  [no-any-return]

antidote (https://github.com/Finistere/antidote)
+ tests/lib/interface/test_custom.py:434: error: Unused "type: ignore" comment  [unused-ignore]
+ tests/lib/interface/test_custom.py:437: error: Unused "type: ignore" comment  [unused-ignore]
+ tests/lib/interface/test_custom.py:440: error: Unused "type: ignore" comment  [unused-ignore]
+ tests/lib/interface/test_custom.py:443: error: Unused "type: ignore" comment  [unused-ignore]
+ tests/lib/interface/test_custom.py:446: error: Unused "type: ignore" comment  [unused-ignore]
+ tests/lib/interface/test_custom.py:449: error: Unused "type: ignore" comment  [unused-ignore]

flake8 (https://github.com/pycqa/flake8): 1.23x slower (22.9s -> 28.1s in single noisy sample)

aioredis (https://github.com/aio-libs/aioredis): 1.30x slower (18.3s -> 23.7s in single noisy sample)

aiortc (https://github.com/aiortc/aiortc): 1.36x slower (23.6s -> 32.1s in single noisy sample)

twine (https://github.com/pypa/twine): 1.15x slower (29.7s -> 34.1s in single noisy sample)

bandersnatch (https://github.com/pypa/bandersnatch): 1.13x slower (41.9s -> 47.5s in single noisy sample)

pyp (https://github.com/hauntsaninja/pyp): 1.47x faster (12.7s -> 8.6s in single noisy sample)

core (https://github.com/home-assistant/core): 1.05x slower (464.0s -> 487.4s in single noisy sample)
- homeassistant/components/energieleser/const.py:25: error: Returning Any from function declared to return "str"  [no-any-return]
- homeassistant/components/zonneplan/coordinator.py:179: error: Returning Any from function declared to return "tuple[Any | None, Any | None]"  [no-any-return]
- homeassistant/components/zonneplan/coordinator.py:192: error: Returning Any from function declared to return "tuple[Any | None, Any | None]"  [no-any-return]
+ homeassistant/components/device_automation/__init__.py:245: error: Unused "type: ignore" comment  [unused-ignore]
+ homeassistant/components/device_automation/__init__.py:245: error: Incompatible return value type (got "list[Any | BaseException]", expected "list[list[dict[str, Any]] | Exception]")  [return-value]
+ homeassistant/components/device_automation/__init__.py:245: note: Error code "return-value" not covered by "type: ignore[no-any-return]" comment
+ homeassistant/components/airos/coordinator.py:128: error: Returning Any from function declared to return "dict[str, Any]"  [no-any-return]
+ homeassistant/components/tplink_omada/diagnostics.py:73: error: Returning Any from function declared to return "dict[str, Any]"  [no-any-return]
+ homeassistant/components/amcrest/camera.py:156: error: Returning Any from function declared to return "bytes | None"  [no-any-return]
+ homeassistant/components/knx/storage/entity_store_validation.py:68: error: Returning Any from function declared to return "dict[Any, Any]"  [no-any-return]
+ homeassistant/components/husqvarna_automower/diagnostics.py:48: error: Returning Any from function declared to return "dict[str, Any]"  [no-any-return]
+ homeassistant/components/airzone_cloud/diagnostics.py:132: error: Returning Any from function declared to return "dict[str, Any]"  [no-any-return]
+ homeassistant/components/motioneye/media_source.py:229: error: Unused "type: ignore" comment  [unused-ignore]
- homeassistant/components/esphome/serial_proxy.py:107: error: Item "None" of "Any | None" has no attribute "_loop"  [union-attr]
- homeassistant/components/uptimerobot/sensor.py:73: error: Returning Any from function declared to return "str | None"  [no-any-return]
+ homeassistant/components/lametric/diagnostics.py:26: error: Returning Any from function declared to return "dict[str, Any]"  [no-any-return]
+ homeassistant/components/open_meteo/diagnostics.py:22: error: Returning Any from function declared to return "dict[str, Any]"  [no-any-return]
+ homeassistant/components/velux/cover.py:111: error: Item "None" of "str | None" has no attribute "upper"  [union-attr]

pytest-robotframework (https://github.com/detachhead/pytest-robotframework)
- pytest_robotframework/_internal/robot/utils.py:249: error: Argument 1 to "reduce" has incompatible type "Callable[[Mapping[str, object], Mapping[str, object]], dict[str, object]]"; expected "Callable[[SupportsKeysAndGetItem[str, object], Mapping[str, object]], SupportsKeysAndGetItem[str, object]]"  [arg-type]

pandera (https://github.com/pandera-dev/pandera)
- tests/ibis/test_ibis_dtypes.py:81: error: Unsupported operand types for + ("list[type[String] | type[_PhysicalNumber]]" and "list[type[Map]]")  [operator]
- tests/ibis/test_ibis_dtypes.py:92: error: Unsupported operand types for + ("list[type[String] | type[_PhysicalNumber]]" and "list[type[Map]]")  [operator]

werkzeug (https://github.com/pallets/werkzeug)
+ src/werkzeug/local.py:59: error: Returning Any from function declared to return "Iterator[tuple[str, Any]]"  [no-any-return]
+ tests/test_exceptions.py:123: error: Unused "type: ignore" comment  [unused-ignore]

pydantic (https://github.com/pydantic/pydantic)
- pydantic/fields.py:844: note:     def Field(default, default: EllipsisType, *, alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: bool | None = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> Any
+ pydantic/fields.py:844: note:     def Field(default: EllipsisType, *, alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: bool | None = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> Any
- pydantic/fields.py:844: note:     def Field(default, default: Any, *, alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[True], repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> Any
+ pydantic/fields.py:844: note:     def Field(default: Any, *, alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[True], repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> Any
- pydantic/fields.py:844: note:     def [_T] Field(default, default: _T, *, alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[False] = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> _T
+ pydantic/fields.py:844: note:     def [_T] Field(default: _T, *, alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[False] = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> _T
- pydantic/fields.py:844: note:     def Field(default_factory, *, default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any], alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[True], repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> Any
+ pydantic/fields.py:844: note:     def Field(*, default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any], alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[True], repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> Any
- pydantic/fields.py:844: note:     def [_T] Field(default_factory, *, default_factory: Callable[[], _T] | Callable[[dict[str, Any]], _T], alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[False] | None = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> _T
+ pydantic/fields.py:844: note:     def [_T] Field(*, default_factory: Callable[[], _T] | Callable[[dict[str, Any]], _T], alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[False] | None = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> _T
- pydantic/fields.py:844: note:     def Field(alias, *, alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: bool | None = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> Any
+ pydantic/fields.py:844: note:     def Field(*, alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | Discriminator | None = ..., deprecated: deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: bool | None = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: SupportsGt | None = ..., ge: SupportsGe | None = ..., lt: SupportsLt | None = ..., le: SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ...) -> Any

scipy (https://github.com/scipy/scipy): 1.06x slower (110.7s -> 117.3s in single noisy sample)
- scipy/stats/tests/test_sampling.py:155: error: Unsupported operand types for + ("list[tuple[tuple[int, ...], type[ValueError], str] | tuple[tuple[int, int], type[UNURANError], str]]" and "list[tuple[tuple[float, float], type[ValueError], str]]")  [operator]

pandas-stubs (https://github.com/pandas-dev/pandas-stubs): 1.08x slower (337.4s -> 364.0s in single noisy sample)
+ tests/indexes/test_indexes.py:181: error: Unused "type: ignore" comment  [unused-ignore]

cwltool (https://github.com/common-workflow-language/cwltool): 1.18x faster (73.3s -> 62.3s in single noisy sample)

rotki (https://github.com/rotki/rotki): 1.06x slower (93.0s -> 98.9s in single noisy sample)
+ rotkehlchen/chain/evm/decoding/stakedao/decoder.py:316: error: Unused "type: ignore" comment  [unused-ignore]

pytest-autoprofile (https://gitlab.com/TTsangSC/pytest-autoprofile): 2.87x slower (10.7s -> 30.7s in single noisy sample)

sympy (https://github.com/sympy/sympy)
+ sympy/core/add.py:396: error: Unused "type: ignore" comment  [unused-ignore]
+ sympy/polys/compatibility.py:402: error: Unused "type: ignore" comment  [unused-ignore]

scikit-learn (https://github.com/scikit-learn/scikit-learn): 1.16x slower (124.3s -> 144.4s in single noisy sample)
- sklearn/externals/array_api_compat/numpy/linalg.py:185: error: Incompatible types in assignment (expression has type "Callable[..., float64]", variable has type overloaded function)  [assignment]
- sklearn/preprocessing/tests/test_polynomial.py:663: error: Unsupported operand types for + ("list[ABCMeta | None]" and "list[ABCMeta]")  [operator]
- sklearn/preprocessing/tests/test_polynomial.py:734: error: Unsupported operand types for + ("list[ABCMeta | None]" and "list[ABCMeta]")  [operator]
- sklearn/preprocessing/tests/test_function_transformer.py:124: error: Unsupported operand types for + ("list[ABCMeta | None]" and "list[ABCMeta]")  [operator]
- sklearn/metrics/tests/test_pairwise.py:946: error: Unsupported operand types for + ("list[overloaded function]" and "list[ABCMeta]")  [operator]
- sklearn/metrics/tests/test_pairwise.py:951: error: Unsupported operand types for + ("list[overloaded function]" and "list[ABCMeta]")  [operator]
- sklearn/metrics/tests/test_pairwise.py:964: error: Unsupported operand types for + ("list[overloaded function]" and "list[ABCMeta]")  [operator]
- sklearn/metrics/tests/test_pairwise.py:1052: error: Unsupported operand types for + ("list[overloaded function]" and "list[ABCMeta]")  [operator]
- sklearn/metrics/tests/test_pairwise.py:1057: error: Unsupported operand types for + ("list[overloaded function]" and "list[ABCMeta]")  [operator]
- sklearn/metrics/tests/test_pairwise.py:1083: error: Unsupported operand types for + ("list[overloaded function]" and "list[ABCMeta]")  [operator]
- sklearn/metrics/tests/test_pairwise.py:1107: error: Unsupported operand types for + ("list[overloaded function]" and "list[ABCMeta]")  [operator]
- sklearn/metrics/tests/test_pairwise.py:1112: error: Unsupported operand types for + ("list[overloaded function]" and "list[ABCMeta]")  [operator]
- sklearn/metrics/tests/test_pairwise.py:1138: error: Unsupported operand types for + ("list[overloaded function]" and "list[ABCMeta]")  [operator]
- sklearn/_loss/tests/test_loss.py:224: error: Unsupported operand types for + ("list[tuple[BaseLoss, list[float], list[float]]]" and "list[tuple[BaseLoss, object, list[Any]]]")  [operator]
- sklearn/_loss/tests/test_loss.py:236: error: Unsupported operand types for + ("list[tuple[BaseLoss, list[float], list[float]]]" and "list[tuple[BaseLoss, list[float], object]]")  [operator]
- sklearn/feature_selection/tests/test_variance_threshold.py:14: error: Unsupported operand types for + ("list[ABCMeta | None]" and "list[ABCMeta]")  [operator]
- sklearn/feature_selection/tests/test_variance_threshold.py:31: error: Unsupported operand types for + ("list[None]" and "list[ABCMeta]")  [operator]
- sklearn/feature_selection/tests/test_variance_threshold.py:47: error: Unsupported operand types for + ("list[ABCMeta | None]" and "list[ABCMeta]")  [operator]
- sklearn/feature_selection/tests/test_variance_threshold.py:61: error: Unsupported operand types for + ("list[ABCMeta | None]" and "list[ABCMeta]")  [operator]
- sklearn/utils/tests/test_sparsefuncs.py:451: error: No overload variant of "hstack" matches argument types "list[Any]", "str"  [call-overload]
- sklearn/utils/tests/test_sparsefuncs.py:451: note: Possible overload variants:
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [T] hstack(blocks: Sequence[_CanStack[T]], format: None = ..., dtype: None = ...) -> T
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [ScalarT: number[Any, Any] | numpy.bool[builtins.bool]] hstack(blocks: Sequence[sparray[ScalarT, tuple[int, int]]], format: Literal['bsr'], dtype: None = ...) -> bsr_array[ScalarT]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [ScalarT: number[Any, Any] | numpy.bool[builtins.bool]] hstack(blocks: Sequence[sparray[ScalarT, tuple[int, int]]], format: Literal['coo'], dtype: None = ...) -> coo_array[ScalarT, tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [ScalarT: number[Any, Any] | numpy.bool[builtins.bool]] hstack(blocks: Sequence[sparray[ScalarT, tuple[int, int]]], format: Literal['csc'], dtype: None = ...) -> csc_array[ScalarT]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [ScalarT: number[Any, Any] | numpy.bool[builtins.bool]] hstack(blocks: Sequence[sparray[ScalarT, tuple[int, int]]], format: Literal['csr'], dtype: None = ...) -> csr_array[ScalarT, tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [ScalarT: number[Any, Any] | numpy.bool[builtins.bool]] hstack(blocks: Sequence[sparray[ScalarT, tuple[int, int]]], format: Literal['dia'], dtype: None = ...) -> dia_array[ScalarT]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [ScalarT: number[Any, Any] | numpy.bool[builtins.bool]] hstack(blocks: Sequence[sparray[ScalarT, tuple[int, int]]], format: Literal['dok'], dtype: None = ...) -> dok_array[ScalarT, tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [ScalarT: number[Any, Any] | numpy.bool[builtins.bool]] hstack(blocks: Sequence[sparray[ScalarT, tuple[int, int]]], format: Literal['lil'], dtype: None = ...) -> lil_array[ScalarT]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [T] hstack(blocks: Sequence[_CanStackAs[numpy.bool[builtins.bool], T]], format: None = ..., *, dtype: type[builtins.bool] | type[numpy.bool[builtins.bool]] | dtype[numpy.bool[builtins.bool]] | HasDType[dtype[numpy.bool[builtins.bool]]] | Literal['bool', 'bool_', 'b1', '|b1', '?']) -> T
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['bsr'], dtype: type[builtins.bool] | type[numpy.bool[builtins.bool]] | dtype[numpy.bool[builtins.bool]] | HasDType[dtype[numpy.bool[builtins.bool]]] | Literal['bool', 'bool_', 'b1', '|b1', '?']) -> bsr_array[numpy.bool[builtins.bool]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['coo'], dtype: type[builtins.bool] | type[numpy.bool[builtins.bool]] | dtype[numpy.bool[builtins.bool]] | HasDType[dtype[numpy.bool[builtins.bool]]] | Literal['bool', 'bool_', 'b1', '|b1', '?']) -> coo_array[numpy.bool[builtins.bool], tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['csc'], dtype: type[builtins.bool] | type[numpy.bool[builtins.bool]] | dtype[numpy.bool[builtins.bool]] | HasDType[dtype[numpy.bool[builtins.bool]]] | Literal['bool', 'bool_', 'b1', '|b1', '?']) -> csc_array[numpy.bool[builtins.bool]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['csr'], dtype: type[builtins.bool] | type[numpy.bool[builtins.bool]] | dtype[numpy.bool[builtins.bool]] | HasDType[dtype[numpy.bool[builtins.bool]]] | Literal['bool', 'bool_', 'b1', '|b1', '?']) -> csr_array[numpy.bool[builtins.bool], tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['dia'], dtype: type[builtins.bool] | type[numpy.bool[builtins.bool]] | dtype[numpy.bool[builtins.bool]] | HasDType[dtype[numpy.bool[builtins.bool]]] | Literal['bool', 'bool_', 'b1', '|b1', '?']) -> dia_array[numpy.bool[builtins.bool]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['dok'], dtype: type[builtins.bool] | type[numpy.bool[builtins.bool]] | dtype[numpy.bool[builtins.bool]] | HasDType[dtype[numpy.bool[builtins.bool]]] | Literal['bool', 'bool_', 'b1', '|b1', '?']) -> dok_array[numpy.bool[builtins.bool], tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['lil'], dtype: type[builtins.bool] | type[numpy.bool[builtins.bool]] | dtype[numpy.bool[builtins.bool]] | HasDType[dtype[numpy.bool[builtins.bool]]] | Literal['bool', 'bool_', 'b1', '|b1', '?']) -> lil_array[numpy.bool[builtins.bool]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [T] hstack(blocks: Sequence[_CanStackAs[signedinteger[_32Bit | _64Bit], T]], format: None = ..., *, dtype: type[JustInt] | type[signedinteger[_64Bit]] | dtype[signedinteger[_64Bit]] | HasDType[dtype[signedinteger[_64Bit]]] | Literal['int_', 'int', 'intp', 'n', '<n', '>n']) -> T
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['bsr'], dtype: type[JustInt] | type[signedinteger[_64Bit]] | dtype[signedinteger[_64Bit]] | HasDType[dtype[signedinteger[_64Bit]]] | Literal['int_', 'int', 'intp', 'n', '<n', '>n']) -> bsr_array[signedinteger[_32Bit | _64Bit]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['coo'], dtype: type[JustInt] | type[signedinteger[_64Bit]] | dtype[signedinteger[_64Bit]] | HasDType[dtype[signedinteger[_64Bit]]] | Literal['int_', 'int', 'intp', 'n', '<n', '>n']) -> coo_array[signedinteger[_32Bit | _64Bit], tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['csc'], dtype: type[JustInt] | type[signedinteger[_64Bit]] | dtype[signedinteger[_64Bit]] | HasDType[dtype[signedinteger[_64Bit]]] | Literal['int_', 'int', 'intp', 'n', '<n', '>n']) -> csc_array[signedinteger[_32Bit | _64Bit]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['csr'], dtype: type[JustInt] | type[signedinteger[_64Bit]] | dtype[signedinteger[_64Bit]] | HasDType[dtype[signedinteger[_64Bit]]] | Literal['int_', 'int', 'intp', 'n', '<n', '>n']) -> csr_array[signedinteger[_32Bit | _64Bit], tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['dia'], dtype: type[JustInt] | type[signedinteger[_64Bit]] | dtype[signedinteger[_64Bit]] | HasDType[dtype[signedinteger[_64Bit]]] | Literal['int_', 'int', 'intp', 'n', '<n', '>n']) -> dia_array[signedinteger[_32Bit | _64Bit]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['dok'], dtype: type[JustInt] | type[signedinteger[_64Bit]] | dtype[signedinteger[_64Bit]] | HasDType[dtype[signedinteger[_64Bit]]] | Literal['int_', 'int', 'intp', 'n', '<n', '>n']) -> dok_array[signedinteger[_32Bit | _64Bit], tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['lil'], dtype: type[JustInt] | type[signedinteger[_64Bit]] | dtype[signedinteger[_64Bit]] | HasDType[dtype[signedinteger[_64Bit]]] | Literal['int_', 'int', 'intp', 'n', '<n', '>n']) -> lil_array[signedinteger[_32Bit | _64Bit]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [T] hstack(blocks: Sequence[_CanStackAs[float64, T]], format: None = ..., *, dtype: type[JustFloat] | type[floating[_64Bit]] | dtype[floating[_64Bit]] | HasDType[dtype[floating[_64Bit]]] | Literal['float64', 'double', 'float', 'f8', '<f8', '>f8', 'd']) -> T
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['bsr'], dtype: type[JustFloat] | type[floating[_64Bit]] | dtype[floating[_64Bit]] | HasDType[dtype[floating[_64Bit]]] | Literal['float64', 'double', 'float', 'f8', '<f8', '>f8', 'd']) -> bsr_array[float64]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['coo'], dtype: type[JustFloat] | type[floating[_64Bit]] | dtype[floating[_64Bit]] | HasDType[dtype[floating[_64Bit]]] | Literal['float64', 'double', 'float', 'f8', '<f8', '>f8', 'd']) -> coo_array[float64, tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['csc'], dtype: type[JustFloat] | type[floating[_64Bit]] | dtype[floating[_64Bit]] | HasDType[dtype[floating[_64Bit]]] | Literal['float64', 'double', 'float', 'f8', '<f8', '>f8', 'd']) -> csc_array[float64]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['csr'], dtype: type[JustFloat] | type[floating[_64Bit]] | dtype[floating[_64Bit]] | HasDType[dtype[floating[_64Bit]]] | Literal['float64', 'double', 'float', 'f8', '<f8', '>f8', 'd']) -> csr_array[float64, tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['dia'], dtype: type[JustFloat] | type[floating[_64Bit]] | dtype[floating[_64Bit]] | HasDType[dtype[floating[_64Bit]]] | Literal['float64', 'double', 'float', 'f8', '<f8', '>f8', 'd']) -> dia_array[float64]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['dok'], dtype: type[JustFloat] | type[floating[_64Bit]] | dtype[floating[_64Bit]] | HasDType[dtype[floating[_64Bit]]] | Literal['float64', 'double', 'float', 'f8', '<f8', '>f8', 'd']) -> dok_array[float64, tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['lil'], dtype: type[JustFloat] | type[floating[_64Bit]] | dtype[floating[_64Bit]] | HasDType[dtype[floating[_64Bit]]] | Literal['float64', 'double', 'float', 'f8', '<f8', '>f8', 'd']) -> lil_array[float64]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def [T] hstack(blocks: Sequence[_CanStackAs[complex128, T]], format: None = ..., *, dtype: type[JustComplex] | type[complexfloating[_64Bit, _64Bit]] | dtype[complexfloating[_64Bit, _64Bit]] | HasDType[dtype[complexfloating[_64Bit, _64Bit]]] | Literal['complex', 'complex128', 'cdouble', 'c16', '<c16', '>c16', 'D']) -> T
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['bsr'], dtype: type[JustComplex] | type[complexfloating[_64Bit, _64Bit]] | dtype[complexfloating[_64Bit, _64Bit]] | HasDType[dtype[complexfloating[_64Bit, _64Bit]]] | Literal['complex', 'complex128', 'cdouble', 'c16', '<c16', '>c16', 'D']) -> bsr_array[complex128]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['coo'], dtype: type[JustComplex] | type[complexfloating[_64Bit, _64Bit]] | dtype[complexfloating[_64Bit, _64Bit]] | HasDType[dtype[complexfloating[_64Bit, _64Bit]]] | Literal['complex', 'complex128', 'cdouble', 'c16', '<c16', '>c16', 'D']) -> coo_array[complex128, tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['csc'], dtype: type[JustComplex] | type[complexfloating[_64Bit, _64Bit]] | dtype[complexfloating[_64Bit, _64Bit]] | HasDType[dtype[complexfloating[_64Bit, _64Bit]]] | Literal['complex', 'complex128', 'cdouble', 'c16', '<c16', '>c16', 'D']) -> csc_array[complex128]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['csr'], dtype: type[JustComplex] | type[complexfloating[_64Bit, _64Bit]] | dtype[complexfloating[_64Bit, _64Bit]] | HasDType[dtype[complexfloating[_64Bit, _64Bit]]] | Literal['complex', 'complex128', 'cdouble', 'c16', '<c16', '>c16', 'D']) -> csr_array[complex128, tuple[int, int]]
- sklearn/utils/tests/test_sparsefuncs.py:451: note:     def hstack(blocks: Sequence[sparray[Any, tuple[Any, ...]]], format: Literal['dia'], dtype: type[JustComplex] | type[complexfloating[_64Bit, _64Bit]] | dtype[complexfloating[_64Bit, _64Bit]] | HasDType[dtype[complexfloating[_64Bit, _64Bit]]] | Literal['complex', 'complex128', 'cdouble', 'c16', '<c16', '>c16', 'D']) -> dia_array[complex128]

... (truncated 56 lines) ...

pytest (https://github.com/pytest-dev/pytest)
+ testing/typing_checks.py:78: error: List item 0 has incompatible type "type[ImportError]"; expected "type[Exception]"  [list-item]

pandas (https://github.com/pandas-dev/pandas): 1.13x slower (273.7s -> 308.4s in single noisy sample)
+ pandas/tests/groupby/test_libgroupby.py:153: error: List item 1 has incompatible type "tuple[def group_cumprod(out: ndarray[tuple[Any, ...], dtype[Any]], values: ndarray[tuple[Any, ...], dtype[Any]], labels: ndarray[tuple[Any, ...], dtype[Any]], ngroups: int, is_datetimelike: bool, skipna: bool = ..., mask: ndarray[tuple[Any, ...], dtype[Any]] | None = ..., result_mask: ndarray[tuple[Any, ...], dtype[Any]] | None = ...) -> None, overloaded function]"; expected "tuple[def group_cumsum(out: ndarray[tuple[Any, ...], dtype[Any]], values: ndarray[tuple[Any, ...], dtype[Any]], labels: ndarray[tuple[Any, ...], dtype[Any]], ngroups: int, is_datetimelike: bool, skipna: bool = ..., mask: ndarray[tuple[Any, ...], dtype[Any]] | None = ..., result_mask: ndarray[tuple[Any, ...], dtype[Any]] | None = ...) -> None, overloaded function]"  [list-item]
+ pandas/tests/dtypes/test_missing.py:858: error: Unused "type: ignore" comment  [unused-ignore]
+ pandas/tests/dtypes/test_missing.py:880: error: Unused "type: ignore" comment  [unused-ignore]
+ pandas/conftest.py:1658: error: Unused "type: ignore" comment  [unused-ignore]
+ pandas/tests/arithmetic/test_period.py:141: error: List item 0 has incompatible type "type[list[_T]]"; expected "function"  [list-item]

cvxpy (https://github.com/cvxpy/cvxpy)
+ cvxpy/transforms/scalarize.py:33: error: Incompatible return value type (got "Any | Literal[0]", expected "Minimize | Maximize")  [return-value]

pytensor (https://github.com/pymc-devs/pytensor)
+ pytensor/tensor/einsum.py:297: error: No overload variant of "__setitem__" of "list" matches argument types "int", "list[int]"  [call-overload]
+ pytensor/tensor/einsum.py:297: note: Possible overload variants:
+ pytensor/tensor/einsum.py:297: note:     def __setitem__(self, SupportsIndex, tuple[int, ...], /) -> None
+ pytensor/tensor/einsum.py:297: note:     def __setitem__(self, slice[SupportsIndex | None, SupportsIndex | None, SupportsIndex | None], Iterable[tuple[int, ...]], /) -> None
+ pytensor/tensor/linalg/dtype_utils.py:42: error: Returning Any from function declared to return "dtype[Any]"  [no-any-return]
+ pytensor/tensor/rewriting/ofg.py:46: error: List item 0 has incompatible type "type[Softmax]"; expected "type[TensorSymbolicOp]"  [list-item]
+ pytensor/tensor/rewriting/ofg.py:46: error: List item 1 has incompatible type "type[LogSoftmax]"; expected "type[TensorSymbolicOp]"  [list-item]
+ pytensor/tensor/rewriting/ofg.py:46: error: List item 2 has incompatible type "type[LogSumExp]"; expected "type[TensorSymbolicOp]"  [list-item]

xarray (https://github.com/pydata/xarray)
+ xarray/core/dataarray.py: note: In function "_infer_coords_and_dims":
+ xarray/core/dataarray.py:196: error: Incompatible types in assignment (expression has type "Hashable", variable has type "str")  [assignment]
+ xarray/core/dataarray.py: note: At top level:
+ xarray/tests/test_dataarray.py:442: error: Unused "type: ignore" comment  [unused-ignore]

ibis (https://github.com/ibis-project/ibis): 1.07x slower (102.0s -> 109.6s in single noisy sample)
- ibis/expr/operations/udf.py:144: error: Dict entry 1 has incompatible type "str": "InputType"; expected "str": "Argument"  [dict-item]
- ibis/expr/operations/udf.py:147: error: Dict entry 2 has incompatible type "str": "property"; expected "str": "Argument"  [dict-item]
- ibis/expr/operations/udf.py:148: error: Dict entry 3 has incompatible type "str": "FrozenDict[Never, Never]"; expected "str": "Argument"  [dict-item]
- ibis/expr/operations/udf.py:149: error: Dict entry 4 has incompatible type "str": "Namespace"; expected "str": "Argument"  [dict-item]
- ibis/expr/operations/udf.py:150: error: Dict entry 5 has incompatible type "str": "str"; expected "str": "Argument"  [dict-item]
- ibis/expr/operations/udf.py:151: error: Dict entry 6 has incompatible type "str": "str"; expected "str": "Argument"  [dict-item]

dd-trace-py (https://github.com/DataDog/dd-trace-py): 1.05x slower (90.0s -> 94.6s in single noisy sample)
+ ddtrace/internal/assembly.py:280: error: Returning Any from function declared to return "Iterator[Any]"  [no-any-return]
- ddtrace/llmobs/_integrations/pydantic_ai.py:132: error: Incompatible return value type (got "tuple[Any | str, Any | None]", expected "tuple[str, str]")  [return-value]
+ ddtrace/llmobs/_integrations/pydantic_ai.py:132: error: Incompatible return value type (got "tuple[Any | str, str | Any | None]", expected "tuple[str, str]")  [return-value]
- ddtrace/testing/internal/pytest/plugin.py:1544: error: Unsupported operand types for + ("list[tuple[str, object]]" and "list[tuple[str, bool]]")  [operator]

jax (https://github.com/google/jax)
- jax/_src/lax/control_flow/conditionals.py:181: error: Incompatible types in assignment (expression has type "tuple[tuple[str, ...] | None, ...]", target has type "tuple[Jaxpr, ...]")  [assignment]
+ jax/_src/numpy/lax_numpy.py:2230: error: Unsupported operand types for - ("Sequence[int | Any]" and "int")  [operator]
+ jax/_src/numpy/lax_numpy.py:2230: note: Left operand is of type "Sequence[int | Any] | int | Any"

meson (https://github.com/mesonbuild/meson)
- mesonbuild/backend/ninjabackend.py:2362:40: error: Incompatible types in assignment (expression has type "list[str]", variable has type "list[Program | BuildTarget | CustomTarget | CustomTargetIndex | File | str]")  [assignment]
- mesonbuild/backend/ninjabackend.py:2362:40: note: "list" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
- mesonbuild/backend/ninjabackend.py:2362:40: note: Consider using "Sequence" instead, which is covariant
- mesonbuild/backend/ninjabackend.py:2362:78: error: Unsupported operand types for + ("list[str]" and "list[Program | BuildTarget | CustomTarget | CustomTargetIndex | File | str]")  [operator]

apprise (https://github.com/caronc/apprise): 1.07x slower (76.1s -> 81.3s in single noisy sample)

mongo-python-driver (https://github.com/mongodb/mongo-python-driver)
+ pymongo/synchronous/encryption.py:133: error: Redundant cast to "Collection[RawBSONDocument]"  [redundant-cast]
+ pymongo/asynchronous/encryption.py:134: error: Redundant cast to "AsyncCollection[RawBSONDocument]"  [redundant-cast]

static-frame (https://github.com/static-frame/static-frame)
+ static_frame/core/util.py:2514: error: Returning Any from function declared to return "timedelta64[Any]"  [no-any-return]
+ static_frame/core/store.py:202: error: Argument 1 to "extend" of "list" has incompatible type "Sequence[TLabel]"; expected "Iterable[tuple[str, ...]]"  [arg-type]
+ static_frame/core/store.py:204: error: Argument 1 to "extend" of "list" has incompatible type "range"; expected "Iterable[tuple[str, ...]]"  [arg-type]
+ static_frame/core/store.py:204: note: Following member(s) of "range" have conflicts:
+ static_frame/core/store.py:204: note:     Expected:
+ static_frame/core/store.py:204: note:         def __iter__(self) -> Iterator[tuple[str, ...]]
+ static_frame/core/store.py:204: note:     Got:
+ static_frame/core/store.py:204: note:         def __iter__(self) -> Iterator[int]

scikit-build-core (https://github.com/scikit-build/scikit-build-core): 1.33x slower (97.6s -> 130.3s in single noisy sample)

black (https://github.com/psf/black): 1.52x slower (37.1s -> 56.3s in single noisy sample)

alectryon (https://github.com/cpitclaudel/alectryon): 1.61x slower (15.3s -> 24.7s in single noisy sample)
- alectryon/core.py:251: error: Argument 3 to "ungroup_by" has incompatible type "Callable[[T], K | None]"; expected "Callable[[T | U], K | None]"  [arg-type]

@ilevkivskyi

Copy link
Copy Markdown
Member Author

Hm, this issue with join of type objects is actually quite bad. To be clear, it also exists on master, for example this fails with a bizarre error on master:

class B:
    def __init__(self, *, y=None) -> None: ...
class C1(B):
    def __init__(self, *, x) -> None: ...
class C2(B): ...

x = [C1, C2]  # E: List item 0 has incompatible type "type[C1]"; expected "type[B]"

But as I expected, some meet/join bugs become more prominent. I tried a conservative fix, but it only fixes the problem partially. We may need to re-think how we join type objects. I think the only potential option may be to use TypeType (not CallableType as now) as a join of two type objects. This will have an issues if someone will try to call an items of the list (they will get supertype signature), but this is kind of consistent with how join behaves in the classic "join vs union" debate.

I am still not sure whether to put the TypeType thing into a separate PR (it is small, but there may be non-trivial fallout).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant